package com.hitqz.robot.biz.flow.component.agv;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.hitqz.robot.api.business.enums.NavEnum;
import com.hitqz.robot.api.business.model.dto.FlowContextDto;
import com.hitqz.robot.api.business.model.dto.FlowPatrolPreAndEndTicketsDto;
import com.hitqz.robot.api.common.entity.Robot;
import com.hitqz.robot.api.common.entity.RobotMapPos;
import com.hitqz.robot.api.common.entity.TicketsTask;
import com.hitqz.robot.biz.business.dispatch.DispatchService;
import com.hitqz.robot.biz.flow.config.FlowInterruptException;
import com.hitqz.robot.biz.flow.util.LiteFlowUtil;
import com.hitqz.robot.biz.service.RobotMapPosService;
import com.hitqz.robot.biz.service.RobotService;
import com.hitqz.robot.driver.model.IRobotPosDto;
import com.hitqz.robot.driver.model.RobotIOStatusDto;
import com.hitqz.robot.driver.parent.RobotDriverService;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author xupkun
 * @date 2025/2/26
 */
@Slf4j
@LiteflowComponent(value = "WaitForFrontPut", name = "[轮对/轮轴]前信号找轮对")
@AllArgsConstructor
public class WaitForFrontPut extends NodeComponent {

    private final RobotDriverService robotDriverService;

    private final RobotMapPosService robotMapPosService;

    private final RobotService robotService;

    private final DispatchService dispatchService;

    private static final int CMD_INVALID = -1;



    @Override
    public void process() throws Exception {
        LiteFlowUtil.checkInterruptFlag();
        //IRobotPosDto iRobotPosDto = robotDriverService.getWebPos();
        FlowContextDto dto =  this.getRequestData();
        TicketsTask task = dto.getTicketsTask();
        log.info("任务数据 {}", task.getParseOrderParams());
        Robot robot = robotService.getDefaultRobot();
        FlowPatrolPreAndEndTicketsDto ticketsDto = JSONObject.parseObject(dto.getTicketsTask()
                .getParseOrderParams(), FlowPatrolPreAndEndTicketsDto.class);
        //String sourceName = Optional.ofNullable(ticketsDto.getModalData().get("sourcePosName"))
        //        .orElse(ticketsDto.getModalData().get("sourcePosCode")).toString();
        String targetPosName = Optional.ofNullable(ticketsDto.getModalData().get("targetPosName"))
                .orElse(ticketsDto.getModalData().get("targetPosCode")).toString();

        RobotMapPos robotMapPos = robotMapPosService.getOne(Wrappers.<RobotMapPos>lambdaQuery()
                .eq(RobotMapPos::getName, targetPosName)
                .eq(RobotMapPos::getMapCode, robot.getMapCode()));
        if (robotMapPos == null) {
            robotMapPos = robotMapPosService.getOne(Wrappers.<RobotMapPos>lambdaQuery()
                    .eq(RobotMapPos::getCode, targetPosName)
                    .eq(RobotMapPos::getMapCode, robot.getMapCode()));
        }
        log.info("前往终端目标点{}", robotMapPos.getCode());
        boolean isSuccess = dispatchService.go2TargetPosition(robotMapPos, false);
        while (true) {
            try {
                IRobotPosDto iRobotPosDto = robotDriverService.getWebPos();
                LiteFlowUtil.checkInterruptFlag();
                if (iRobotPosDto == null || iRobotPosDto.getTaskStatus() == null) {
                    continue;
                }
                Cache<String, Integer> cmdNav = SpringUtil.getBean("cmdNav");
                Integer cmd = cmdNav.getIfPresent(robot.getRobotSn());
                if (iRobotPosDto.getTaskStatus() != null) {
                    int taskStatus = iRobotPosDto.getTaskStatus();
                    boolean isSuspendedOrFailed = taskStatus == NavEnum.SUSPENDED.getCode()
                            || taskStatus == NavEnum.FAILED.getCode() ||
                            taskStatus == NavEnum.CANCEL.getCode() || taskStatus == NavEnum.COMPLETED.getCode();
                    boolean isCmdInvalid = cmd == null || cmd == CMD_INVALID;
                    log.info("导航的状态: {} --- {}----cmd {}---{} ",
                            iRobotPosDto.getTaskStatus(),
                            isSuspendedOrFailed,
                            isCmdInvalid,
                            cmd);
                    if (isSuspendedOrFailed && isCmdInvalid) {
                        iRobotPosDto = robotDriverService.getWebPos();
                        if (iRobotPosDto == null || iRobotPosDto.getTaskStatus() == null) {
                            continue;
                        }
                        RobotIOStatusDto robotIOStatusDto = iRobotPosDto.getDI().stream().filter(
                                t-> t.getId() == 3).findFirst().get();
                        for (int i = 0; i < 20; i ++) {
                            if (robotIOStatusDto.isStatus()) {
                                log.info("循环{}次数可以放下去:", i, robotIOStatusDto.isStatus());
                                break;
                            } else {
                                iRobotPosDto = robotDriverService.getWebPos();
                                robotIOStatusDto = iRobotPosDto.getDI().stream().filter(
                                        t-> t.getId() == 0).findFirst().get();
                                log.info("循环重新获取：" + robotIOStatusDto.isStatus());
                                Thread.sleep(300);
                            }
                        }
                        log.info("前面的传感器数据: {}---{}", robotIOStatusDto.getId(), robotIOStatusDto.isStatus());
                    }
                    TimeUnit.SECONDS.sleep(1);
                }
            } catch (Exception e) {
                log.info("解析异常:" +e.getMessage());
                if (e instanceof FlowInterruptException) {
                    log.info("流程被中断");
                    break;
                }
            }
        }
    }
}
